package net.zoneland.knowledge.controller.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.exceptions.WorkApplyException;
import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 解析选人控件数据的工具类。
 */
public class UserSelectItemUtils {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    private static final TypeReference<List<List<UserSelectItem>>> DOUBLE_LIST_USER_SELECT_ITEM_TYPE_REFERENCE = new TypeReference<List<List<UserSelectItem>>>() {
    };

    private static final TypeReference<List<UserSelectItem>> LIST_USER_SELECT_ITEM_TYPE_REFERENCE = new TypeReference<List<UserSelectItem>>() {
    };

    /**
     * 解析人员选择控件的所选的人员。
     *
     * @param sourceString 选人控件所产生的name字段
     * @return 双层列表，外层List的每个元素表示一组，内层List每个元素表示人
     */
    public static List<List<UserSelectItem>> convertToListListUserSelectItem(String sourceString) {
        if (StringUtils.isBlank(sourceString)) {
            return Lists.newArrayList();
        }

        try {
            return OBJECT_MAPPER.readValue(sourceString, DOUBLE_LIST_USER_SELECT_ITEM_TYPE_REFERENCE);
        } catch (JsonProcessingException e) {
            throw new WorkApplyException("解析选人员选择控件数据出错，sourceString:" + sourceString, e);
        }
    }

    /**
     * 解析人员选择控件的所选的人员。
     *
     * @param sourceString 选人控件所产生的name字段
     * @return 双层列表，外层List的每个元素表示一组，内层List每个元素表示人
     */
    public static List<UserSelectItem> convertToListUserSelectItem(String sourceString) {
        if (StringUtils.isBlank(sourceString)) {
            return Lists.newArrayList();
        }

        try {
            return OBJECT_MAPPER.readValue(sourceString, LIST_USER_SELECT_ITEM_TYPE_REFERENCE);
        } catch (JsonProcessingException e) {
            throw new WorkApplyException("解析选人员选择控件数据出错，sourceString:" + sourceString, e);
        }
    }

    /**
     * 解析人员选择控件的所选的人员，并返回所有人员uid的拼接字符串。
     * @param sourceString 选人控件所产生的name字段
     * @return 所有人员uid的拼接字符串，多值以分号分隔
     */
    public static String convertToUidJoin(String sourceString) {
        return convertToListListUserSelectItem(sourceString).stream()
                .flatMap(list -> list.stream())
                .map(u -> u.getUid())
                .collect(Collectors.joining(Constants.STRING_SEMICOLON));
    }
}
